package com.simpou.commons.persistence.dao;

import com.simpou.commons.model.entity.BaseEntity;
import com.simpou.commons.model.entity.IdentifiableEntity;
import com.simpou.commons.utils.pagination.PageLimits;
import com.simpou.commons.utils.pagination.Paginator;

import java.io.Serializable;

import java.util.List;


/**
 * Define o padrão Data Access Object para persistência básica de objetos
 * genéricos.
 *
 * @author Jonas Pereira
 * @param <T> Tipo dos dados a serem manipulados/acessados.
 * @since 2012-05-17
 * @version 2013-06-01
 */
public interface GenericDAO<T extends BaseEntity> extends BaseDao {
    /**
     * Obtém uma entidade persistida que seja unicamente identificável.
     *
     * @param clasz Classe da entidade desejada.
     * @param id Identificador único da entidade desejada.
     * @return Entidade determinada pelo identificador único.
     * @throws Exception Se houver.
     */
    public <E extends Serializable, T extends IdentifiableEntity<E>> T getSingle(
        final Class<T> clasz, final E id) throws Exception;

    /**
     * Remove uma entidade persistida.
     *
     * @param clasz Classe da entidade a ser removida.
     * @param id Identificador único da entidade a ser removida.
     * @throws Exception Se houver.
     */
    public <E extends Serializable, T extends IdentifiableEntity<E>> void delete(
        final Class<T> clasz, final E id) throws Exception;

    /**
     * <p>getList.</p>
     *
     * @return Lista de todos elementos persistidos.
     * @throws java.lang.Exception Se houver alguma.
     */
    List<T> getList() throws Exception;

    /**
     * Consulta de objetos feita de forma paginada. Evita a manipulação de
     * grandes quantidades de dados desnecessariamente.
     *
     * @see Paginator Veja para auxílio na operação de paginação.
     * @param limits Limitação da busca.
     * @return Lista limitada dos objetos persistidos.
     * @throws java.lang.Exception Se houver alguma.
     */
    List<T> getList(PageLimits limits) throws Exception;

    /**
     * Persiste um novo objeto.
     *
     * @param t Objeto ainda não persistido e que deverá ser.
     * @return Objeto persistido. Pode ser uma nova instância ou a mesma.
     * @throws java.lang.Exception Se houver alguma.
     */
    T create(T t) throws Exception;

    /**
     * Persiste as atualizações em um objeto já persistido.
     *
     * @param t Objeto cuja sua persistência será atualizada.
     * @return Objeto persistido. Pode ser uma nova instância ou a mesma.
     * @throws java.lang.Exception Se houver alguma.
     */
    T update(T t) throws Exception;

    /**
     * Remove um objeto do contexto de persistência atual.
     *
     * @param t Objeto já persistido a ser removido.
     * @throws java.lang.Exception Se houver alguma.
     */
    void delete(T t) throws Exception;

    /**
     * Remove todos objetos do contexto de persistência atual.
     *
     * @throws java.lang.Exception Se houver alguma.
     */
    void deleteAll() throws Exception;

    /**
     * <p>count.</p>
     *
     * @return Quantidade total de objetos persistidos.
     * @throws java.lang.Exception Se houver alguma.
     */
    Long count() throws Exception;
}
